#include "thread/thread.h"
#include "memory/memory.h"
#include "lib/memctrl.h"
#include "lib/print.h"

static void kernel_thread(thread_func *func, void *arg) {
    func(arg);
}

void thread_create(struct task_pcb* pthread, thread_func func, void* func_arg) {
    // 预留中断空间
    pthread->self_kstack -= sizeof(struct intr_frame);

    // 初始化线程栈
    pthread->self_kstack -= sizeof(struct thread_frame);
    struct thread_frame* tf = (struct thread_frame*)pthread->self_kstack;
    tf->eip = kernel_thread;
    tf->func = func;
    tf->func_arg = func_arg;
    tf->ebp = tf->ebx = tf->esi = tf->edi = 0;
}

void init_thread(struct task_pcb* pthread, char* thread_name, int prio) {
    memset_S(pthread, 0, sizeof(*pthread));
    FormatPrint(pthread->name, "%s", thread_name);
    pthread->status = TASK_RUNNING;
    pthread->priority = prio;
    pthread->self_kstack = (uint32_t*)((uint32_t)pthread + PAGE_SIZE);
    pthread->stack_magic = 0x20220901;
}

struct task_pcb* thread_start(char* thread_name, int prio, thread_func func, void* func_arg) {

    struct task_pcb* thread = malloc_sys(APPLY_FOR_KERNEL, PAGE_SIZE);

    init_thread(thread, thread_name, prio);
    thread_create(thread, func, func_arg);

    asm volatile (
                "movl %0, %%esp \n\t"
                "pop %%ebp \n\t"
                "pop %%ebx \n\t"
                "pop %%edi \n\t"
                "pop %%esi \n\t" : : "g" (thread->self_kstack) : "memory");

    return thread;
}